Code Example: Basic Smart Contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract HelloWorld {
string public greeting = "Hello, World!";
function getGreeting() public view returns (string memory) {
return greeting;
}
}
if, else, for, while, and do while.Code Example: Control Flow
pragma solidity ^0.8.0;
contract ControlFlow {
function checkNumber(uint num) public pure returns (string memory) {
if (num > 10) {
return "Greater than 10";
} else if (num == 10) {
return "Equal to 10";
} else {
return "Less than 10";
}
}
}
uint, int, bool, address, and bytes.Code Example: Data Types
pragma solidity ^0.8.0;
contract DataTypes {
uint public number = 42;
bool public isTrue = true;
address public owner = msg.sender;
bytes32 public data = "Hello";
function updateNumber(uint _number) public {
number = _number;
}
}
Code Example: Variables
pragma solidity ^0.8.0;
contract Variables {
uint public stateVariable = 10; // State variable
function getLocalVariable() public pure returns (uint) {
uint localVariable = 20; // Local variable
return localVariable;
}
function getGlobalVariable() public view returns (address) {
return msg.sender; // Global variable
}
}
Code Example: Operators
pragma solidity ^0.8.0;
contract Operators {
function calculate(uint a, uint b) public pure returns (uint) {
uint sum = a + b;
uint product = a * b;
return sum + product;
}
}
Code Example: State Variables and Storage
pragma solidity ^0.8.0;
contract StorageExample {
uint public storedData;
function set(uint x) public {
storedData = x; // Stored permanently in blockchain
}
function get() public view returns (uint) {
return storedData;
}
}
Code Example: Transactions and Gas Fees
pragma solidity ^0.8.0;
contract GasExample {
uint public data;
function storeData(uint x) public {
data = x; // This consumes gas
}
function calculateGas() public view returns (uint) {
return tx.gasprice; // Returns the gas price of the transaction
}
}
Code Example: Events
pragma solidity ^0.8.0;
contract EventExample {
event DataStored(uint data);
function store(uint data) public {
emit DataStored(data); // Emits an event
}
}
Before diving into scenarios and use cases, let’s briefly explain some fundamental concepts, such as msg.sender, msg.value, tx.gasprice, and block.timestamp, that are frequently used in Solidity smart contracts.
msg.sender:
msg.sender represents the caller of the function.Example:
address public owner;
constructor() {
owner = msg.sender; // Sets the owner as the person who deployed the contract
}
msg.value:
Example:
function buyToken() public payable {
require(msg.value == 1 ether, "Send exactly 1 Ether");
// Process token purchase
}
tx.gasprice:
Example:
function getGasPrice() public view returns (uint) {
return tx.gasprice;
}
block.timestamp:
Example:
uint public deadline = block.timestamp + 1 days;
function isExpired() public view returns (bool) {
return block.timestamp > deadline;
}
Here are five common use cases for Solidity smart contracts, each with an example contract demonstrating how the scenario is implemented.
msg.sender, msg.value, payable.Code Example:
pragma solidity ^0.8.0;
contract SimpleWallet {
address public owner;
constructor() {
owner = msg.sender; // The deployer of the contract is the owner
}
// Allow anyone to deposit Ether into the contract
function deposit() public payable {}
// Only the owner can withdraw the balance
function withdraw(uint amount) public {
require(msg.sender == owner, "Only the owner can withdraw");
require(address(this).balance >= amount, "Insufficient balance");
payable(owner).transfer(amount);
}
// Get the balance of the contract
function getBalance() public view returns (uint) {
return address(this).balance;
}
}
block.timestamp, payable, msg.value.Code Example:
pragma solidity ^0.8.0;
contract Auction {
address public owner;
uint public highestBid;
address public highestBidder;
uint public auctionEndTime;
constructor(uint _durationMinutes) {
owner = msg.sender;
auctionEndTime = block.timestamp + _durationMinutes * 1 minutes;
}
// Place a bid during the auction
function bid() public payable {
require(block.timestamp < auctionEndTime, "Auction has ended");
require(msg.value > highestBid, "There already is a higher bid");
highestBid = msg.value;
highestBidder = msg.sender;
}
// End the auction and send the highest bid to the owner
function endAuction() public {
require(msg.sender == owner, "Only the owner can end the auction");
require(block.timestamp >= auctionEndTime, "Auction is still ongoing");
payable(owner).transfer(highestBid);
}
}
msg.value, block.timestamp, refunding contributions.Code Example:
pragma solidity ^0.8.0;
contract Crowdfunding {
address public owner;
uint public goal;
uint public deadline;
mapping(address => uint) public contributions;
constructor(uint _goal, uint _durationMinutes) {
owner = msg.sender;
goal = _goal;
deadline = block.timestamp + _durationMinutes * 1 minutes;
}
// Contribute to the project
function contribute() public payable {
require(block.timestamp < deadline, "Deadline has passed");
contributions[msg.sender] += msg.value;
}
// Claim funds if the goal is met
function claimFunds() public {
require(msg.sender == owner, "Only owner can claim funds");
require(address(this).balance >= goal, "Goal not reached");
require(block.timestamp >= deadline, "Crowdfunding still ongoing");
payable(owner).transfer(address(this).balance);
}
// Refund contributions if the goal is not met
function refund() public {
require(block.timestamp >= deadline, "Crowdfunding still ongoing");
require(address(this).balance < goal, "Goal was reached");
uint contribution = contributions[msg.sender];
contributions[msg.sender] = 0;
payable(msg.sender).transfer(contribution);
}
}
block.timestamp, require, locking mechanism.Code Example:
pragma solidity ^0.8.0;
contract TokenVesting {
address public beneficiary;
uint public releaseTime;
uint public tokenAmount;
constructor(address _beneficiary, uint _tokenAmount, uint _releaseDurationMinutes) {
beneficiary = _beneficiary;
tokenAmount = _tokenAmount;
releaseTime = block.timestamp + _releaseDurationMinutes * 1 minutes;
}
// Claim tokens after the release time
function claimTokens() public {
require(block.timestamp >= releaseTime, "Tokens are still locked");
require(msg.sender == beneficiary, "Only beneficiary can claim tokens");
// Transfer the tokens (pseudo-code)
// _transferTokens(beneficiary, tokenAmount);
}
}
msg.sender, mapping, require.Code Example:
pragma solidity ^0.8.0;
contract Voting {
address public owner;
mapping(string => uint) public votes;
mapping(address => bool) public hasVoted;
constructor() {
owner = msg.sender;
}
// Vote for a proposal
function vote(string memory proposal) public {
require(!hasVoted[msg.sender], "You have already voted");
votes[proposal]++;
hasVoted[msg.sender] = true;
}
// Get the number of votes for a proposal
function getVotes(string memory proposal) public view returns (uint) {
return votes[proposal];
}
// Owner can finalize the vote
function finalizeVote() public {
require(msg.sender == owner, "Only the owner can finalize the vote");
// Finalize voting process (e.g., declare winner)
}
}
Code Example: ERC20 Token
pragma solidity ^0.8.0;
interface IERC20 {
function transfer(address recipient, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
}
contract MyToken is IERC20 {
string public name = "MyToken";
string public symbol = "MTK";
uint8 public decimals = 18;
uint256 public totalSupply = 1000000 * 10**18;
mapping(address => uint256) public balances;
constructor() {
balances[msg.sender] = totalSupply;
}
function transfer(address recipient, uint256 amount) public override returns (bool) {
require(balances[msg.sender] >= amount, "Insufficient balance");
balances[msg.sender] -= amount;
balances[recipient] += amount;
return true;
}
function balanceOf(address account) public view override returns (uint256) {
return balances[account];
}
}
Code Example: ERC721 Token
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract MyNFT is ERC721 {
uint public nextTokenId;
address public admin;
constructor() ERC721('MyNFT', 'MNFT') {
admin = msg.sender;
}
function mint(address to) external {
require(msg.sender == admin, "Only admin can mint");
_safeMint(to, nextTokenId);
nextTokenId++;
}
}